package cn.com.cennavi.fileMake;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import cn.com.cennavi.bean.CloseRoadMapData;
import cn.com.cennavi.bean.DifPointTotalMapInfo;
import cn.com.cennavi.bean.R_G_DATA;
import cn.com.cennavi.util.MapUtil;

import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
import com.vividsolutions.jts.operation.linemerge.LineMerger;

/**
 * 地面道路地图编译文件生成
 * 
 * @ClassName: CloseRoadMapConfigCompile
 * @Description: TODO（这里用一句话描述这个类的作用）
 * @author bull
 * @date 2016年7月11日 上午10:07:14
 *
 */
public class CloseRoadMapConfigCompile {
	private static double bufferAreaDistance = 0.00010;// 缓冲区半径10米
	private static final String R_G_Map_File = "D:\\data\\R-G\\R-G_16map_beijing.csv";
	// public static final String inputFileFolder =
	// "D:\\data\\TrafficLightCrossMap\\TrafficLightCrossMap";
	public static final String closeRoadMapDataFile = "D:\\data\\TrafficLightCrossMap_beijing\\combine.csv";
	// public static final String closeRoadMapDataFile =
	// "C:\\Users\\Thinkpad\\Downloads\\part-00003";
	// public static final String closeRoadTurnAttrFile =
	// "d:\\data\\compileResult_16G_MAP_groundRoad_TurnAttr.csv";
	// public static final String closeRoadLinkLengthFile =
	// "d:\\data\\lonlat_16G_groundRoad_linkLength.csv";
	public static final String outFile = "d:\\data\\DifPointTotalMapInfo_closeRoad_beijing_10mibuf.csv";
	public static final int cellSize = 200;
	public static final int simpleSmallNum = 180;
	public static final int roadClass = 0;

	public static void main(String[] args) throws IOException, ParseException {
		// TODO Auto-generated method stub
		DifPointTotalMapInfo difMap = new DifPointTotalMapInfo();
		// test(outFile);
		/**
		 * 1.link固有的地图属性
		 */

		// 得到link的形状 和长度信息和meshid信息
		HashMap<String, Geometry> linkGeo = new HashMap<String, Geometry>();
		// 得到link的方位角范围
		HashMap<String, String> linkAngle = new HashMap<String, String>();
		// link的meshiD
		HashMap<String, Integer> linklen = new HashMap<String, Integer>();

		// link的长度信息
		HashMap<String, String> linkMeshIds = new HashMap<String, String>();

		getLinkGeo(R_G_Map_File, linkGeo, linklen, linkMeshIds, cellSize, linkAngle);

		/**
		 * 2.操作封闭道路分歧点数据 key:nodeID value:
		 */
		HashMap<String, ArrayList<DifPointTotalMapInfo>> sameNodeRoadsMap = new HashMap<String, ArrayList<DifPointTotalMapInfo>>();

		// 分叉口道路按照nodeid分组--sameNodeRoadsMap
		getSameNodeRoads(closeRoadMapDataFile, sameNodeRoadsMap, simpleSmallNum, roadClass);

		// 按照nodeid+进出口link分组,并设置同行标志
		HashMap<String, ArrayList<DifPointTotalMapInfo>> node_in_out_map = getInOrOutInfo(sameNodeRoadsMap);

		// 获取相同方向上有分叉的道路的公共部分，得到分叉道路最后相同的linkid
		getNode_in_out_map(node_in_out_map);

		// 开始计算长度信息和形状信息以及
		getLinkLenDisGeoInfo(node_in_out_map, linklen, linkGeo, linkMeshIds, linkAngle);

		// 输出node_in_out_map
		outToFile(node_in_out_map, outFile);

	}

	private static void outToFile(HashMap<String, ArrayList<DifPointTotalMapInfo>> node_in_out_map, String outfile2) throws IOException {
		// TODO Auto-generated method stub
		BufferedWriter o = new BufferedWriter(new FileWriter(new File(outfile2)));
		for (Map.Entry<String, ArrayList<DifPointTotalMapInfo>> entry : node_in_out_map.entrySet()) {
			String nodeId_in_out_link = entry.getKey();
			ArrayList<DifPointTotalMapInfo> dataList = entry.getValue();
			for (DifPointTotalMapInfo data : dataList) {
				System.out.println(data.toString1());
			}
		}
	}

	private static void getLinkLenDisGeoInfo(HashMap<String, ArrayList<DifPointTotalMapInfo>> node_in_out_map, HashMap<String, Integer> linklen, HashMap<String, Geometry> linkGeo, HashMap<String, String> linkMeshIds, HashMap<String, String> linkAngle) throws ParseException {
		// TODO Auto-generated method stub
		for (Map.Entry<String, ArrayList<DifPointTotalMapInfo>> entry : node_in_out_map.entrySet()) {
			String nodeId_in_out_link = entry.getKey();
			ArrayList<DifPointTotalMapInfo> dataList = entry.getValue();
			for (DifPointTotalMapInfo data : dataList) {
				String enterLink = data.enter_out_DifPoint_Link.split("\\|")[0];
				String outerLink = data.enter_out_DifPoint_Link.split("\\|")[1];
				String[] linkSeq = data.linkArr.split("\\|");
				StringBuffer linkLenuf = new StringBuffer();
				int difIedex = 0;
				HashSet<String> meshIds = new HashSet<String>();
				for (int i = 0; i < linkSeq.length; i++) {
					int len = linklen.get(linkSeq[i]);
					linkLenuf.append(linkSeq[i]);
					linkLenuf.append(":");
					linkLenuf.append(len);
					if (i != linkSeq.length - 1) {
						linkLenuf.append("|");
					}
					// if("01".equals(data.dir)||"11".equals(data.dir)){
					// if (linkSeq[i].equals(outerLink)) {
					// difIedex = i;
					// }
					// }else{
					// if (linkSeq[i].equals(enterLink)) {
					// difIedex = i;
					// }
					// }
					if (linkSeq[i].equals(outerLink)) {
						difIedex = i;
					}

					String[] meshs = linkMeshIds.get(linkSeq[i]).split("\\|");
					for (String meshID : meshs) {
						meshIds.add(meshID);
					}

				}
				String[] dis = data.LinkDisArr.split("\\|");
				data.dif_Point_Dis = Integer.parseInt(dis[difIedex]);
				data.difPoint_startDis = data.totalLength - data.dif_Point_Dis;
				data.difPoint_angle = data.straight_angle;
				data.linksLen = linkLenuf.toString();
				data.meshIdSeq = getMeshIds(meshIds);
				getRoadGEO(data, linkGeo);
				getMinMaxAzimuth(data, linkAngle);
			}
			// 计算minSuitableDisFromLastLink\maxSuitableDisFromLastLink
			if (dataList.size() > 1) {
				// System.out.println("有分叉！");
				// 获取数据的lastSameLink和firstSameLink
				for (DifPointTotalMapInfo data : dataList) {
					String firstSameLink = data.firstSameLink;
					String lastSameLink = data.lastSameLink;
					String[] linkSeq = data.linkArr.split("\\|");
					int minindex = 0;
					int maxindex = 0;
					for (int i = 0; i < linkSeq.length; i++) {
						if (linkSeq[i].equals(lastSameLink)) {
							minindex = i;
							continue;
						}
					}
					for (int i = 0; i < linkSeq.length; i++) {
						if (linkSeq[i].equals(firstSameLink)) {
							maxindex = i;
							continue;
						}
					}
					String[] disSeq = data.LinkDisArr.split("\\|");

					int maxSuitableDisFromLastLink = data.totalLength - Integer.parseInt(disSeq[maxindex]);
					data.maxSuitableDisFromLastLink = maxSuitableDisFromLastLink;
					if (minindex == disSeq.length - 1) {
						int minSuitableDisFromLastLink = 0;

						data.minSuitableDisFromLastLink = minSuitableDisFromLastLink;
						data.samelinkLen = maxSuitableDisFromLastLink - minSuitableDisFromLastLink;
					} else {
						int minSuitableDisFromLastLink = data.totalLength - Integer.parseInt(disSeq[minindex + 1]);
						data.minSuitableDisFromLastLink = minSuitableDisFromLastLink;

						data.samelinkLen = maxSuitableDisFromLastLink - minSuitableDisFromLastLink;
					}

				}

			} else {
				// 说明单方向上没有分叉的情况
				dataList.get(0).maxSuitableDisFromLastLink = dataList.get(0).totalLength;
				dataList.get(0).minSuitableDisFromLastLink = 0;
				dataList.get(0).samelinkLen = dataList.get(0).totalLength - 0;
			}

		}
	}

	private static void getMinMaxAzimuth(DifPointTotalMapInfo data, HashMap<String, String> linkAngle) {
		// TODO Auto-generated method stub
		String[] linkSeq = data.linkArr.split("\\|");
		// LineMerger lineMerger = new LineMerger();
		// List<Geometry> list = new ArrayList<Geometry>();
		// TreeMap<Double, Double> minmaxMap = new TreeMap<Double, Double>();
		// for (String link : linkSeq) {
		// String minmaxAngle = linkAngle.get(link);
		// if (minmaxAngle != null) {
		// String[] minmax = minmaxAngle.split("\\_");
		// double minangle = Double.parseDouble(minmax[0]);
		// double maxangle = Double.parseDouble(minmax[1]);
		// minmaxMap.put(minangle, minangle);
		// minmaxMap.put(maxangle, maxangle);
		// }
		// }
		// data.min_Azimuth = minmaxMap.firstKey();
		// data.max_Azimuth = minmaxMap.lastKey();
		String intAngle = linkAngle.get(linkSeq[0]);
		String outAngle = linkAngle.get(linkSeq[linkSeq.length - 1]);
		String[] ang1 = intAngle.split("\\_");
		String[] ang2 = outAngle.split("\\_");
		// LineMerger lineMerger = new LineMerger();
		// List<Geometry> list = new ArrayList<Geometry>();
		// TreeMap<Double, Double> minmaxMap = new TreeMap<Double, Double>();
		// for (String link : linkSeq) {
		// String minmaxAngle = linkAngle.get(link);
		// if (minmaxAngle != null) {
		// String[] minmax = minmaxAngle.split("\\_");
		// double minangle = Double.parseDouble(minmax[0]);
		// double maxangle = Double.parseDouble(minmax[1]);
		// minmaxMap.put(minangle, minangle);
		// minmaxMap.put(maxangle, maxangle);
		// }
		// }
		data.enter_Azimuth = Double.parseDouble(ang1[0]);
		data.out_Azimuth = Double.parseDouble(ang2[1]);
	}

	/**
	 * 获取link序列形状
	 * 
	 * @param data
	 * @param linkGeo
	 * @return
	 * @throws ParseException
	 */
	private static void getRoadGEO(DifPointTotalMapInfo data, HashMap<String, Geometry> linkGeo) throws ParseException {
		// TODO Auto-generated method stub
		String[] linkSeq = data.linkArr.split("\\|");
		LineMerger lineMerger = new LineMerger();
		List<Geometry> list = new ArrayList<Geometry>();
		for (String link : linkSeq) {
			Geometry geo = linkGeo.get(link);
			if (geo != null) {
				list.add(geo);
			}
		}
		lineMerger.add(list);
		Collection<Geometry> mergerLineStrings = lineMerger.getMergedLineStrings();
		for (Geometry dpr : mergerLineStrings) {
			Geometry g1 = new WKTReader().read(dpr.toString());
			Geometry buffer = g1.buffer(bufferAreaDistance);
			// BufferOp bufOp = new BufferOp(g);
			// bufOp.setQuadrantSegments(0);
			// System.out.println(buffer.toString());
			data.roadGeo = buffer;

		}
	}

	/**
	 * 获取所有的mesh
	 * 
	 * @param meshIds
	 * @return
	 */
	private static String getMeshIds(HashSet<String> meshIds) {
		// TODO Auto-generated method stub
		StringBuffer sf = new StringBuffer();
		for (String meshId : meshIds) {
			sf.append(meshId);
			sf.append("|");
		}
		return sf.toString().substring(0, sf.toString().length() - 1);
	}

	private static void getNode_in_out_map(HashMap<String, ArrayList<DifPointTotalMapInfo>> node_in_out_map) {
		// TODO Auto-generated method stub
		for (Map.Entry<String, ArrayList<DifPointTotalMapInfo>> entry : node_in_out_map.entrySet()) {
			String nodeId_in_out_link = entry.getKey();
			ArrayList<DifPointTotalMapInfo> dataList = entry.getValue();
			if (dataList.size() > 1) {
				getLastSameLink(dataList);
			} else {
				// 说明单方向上没有分叉的情况
			}
		}
	}

	/**
	 * 得到相同方向但是有分叉的公共link
	 * 
	 * @param dataList
	 * @return
	 */
	private static void getLastSameLink(ArrayList<DifPointTotalMapInfo> dataList) {
		// TODO Auto-generated method stub
		String maxSameStr = dataList.get(0).linkArr;
		for (int i = 1; i < dataList.size(); i++) {
			String linkSeqbef = dataList.get(i).linkArr;
			maxSameStr = getCommonStrLength(maxSameStr, linkSeqbef);

		}
		String[] link = maxSameStr.split("\\|");
		String lastSameLink = link[link.length - 1];
		String firstSameLink = link[0];
		for (int i = 0; i < dataList.size(); i++) {
			dataList.get(i).lastSameLink = lastSameLink;
			dataList.get(i).firstSameLink = firstSameLink;
		}
	}

	private static String getCommonStrLength(String str1, String str2) {
		// TODO Auto-generated method stub
		// 12644678|12644677|500679|15086815|15086814|493704|448224
		// 12644678|12644677|500679|15086815|15086814|493704|448225
		String[] arr1 = str1.split("\\|");
		String[] arr2 = str2.split("\\|");
		String line = "";
		for (int i = 0; i < arr1.length; i++) {
			String str = line + arr1[i];
			if (str2.contains(str)) {
				line += arr1[i];
				if (i != arr1.length - 1) {
					line += "|";
				}
			} else {
				continue;
			}
		}
		if (line.endsWith("|")) {
			line = (String) line.subSequence(0, line.length() - 1);
		}
		return line;
	}

	/**
	 * 按照node分好组后，每一组中，如果进入link一样则为汇出，出去link一样则为汇入
	 * 
	 * @param sameNodeRoadsMap
	 */
	private static HashMap<String, ArrayList<DifPointTotalMapInfo>> getInOrOutInfo(HashMap<String, ArrayList<DifPointTotalMapInfo>> sameNodeRoadsMap) {
		// TODO Auto-generated method stub
		HashMap<String, ArrayList<DifPointTotalMapInfo>> dataMap = new HashMap<String, ArrayList<DifPointTotalMapInfo>>();
		for (Map.Entry<String, ArrayList<DifPointTotalMapInfo>> entry : sameNodeRoadsMap.entrySet()) {
			String nodeId = entry.getKey();
			ArrayList<DifPointTotalMapInfo> dataList = entry.getValue();
			String inoutLink = dataList.get(0).enter_out_DifPoint_Link;
			if (dataList.size() > 1) {
				// 判断该分歧点是汇入点还是汇出 点:00表示左出，10表示右出，01表示左入，11表示右入
				String dirFlag = getDirFlag(dataList);

				if (dirFlag != null) {
					// 设置方向
					setDirFlag(dirFlag, dataList);
					for (DifPointTotalMapInfo data : dataList) {
						String key = nodeId + "_" + data.enter_out_DifPoint_Link;
						ArrayList<DifPointTotalMapInfo> value = dataMap.get(key);
						if (value == null) {
							value = new ArrayList<DifPointTotalMapInfo>();
							value.add(data);
							dataMap.put(key, value);
						} else {
							value.add(data);
							// System.out.println("1有分叉口");
						}
					}

				}
			} else {
				// System.out.println("分叉口道路只有一条道路有记录！");
			}

		}
		return dataMap;
	}

	/**
	 * 设置每条道路的同行方向
	 * 
	 * @param dirFlag
	 * @param dataList
	 */
	private static void setDirFlag(String dirFlag, ArrayList<DifPointTotalMapInfo> dataList) {
		// TODO Auto-generated method stub
		for (DifPointTotalMapInfo data : dataList) {
			int flag = data.flag;
			// zhixing
			if (flag == 0) {
				data.flag = 0;
			} else {
				if (dirFlag.equals("00") || dirFlag.equals("10")) {
					data.flag = 1;
				} else {
					data.flag = 2;
				}
			}
			data.dir = dirFlag;
		}
	}

	/**
	 * 获取同行标志是汇入还是汇出:00表示左出，10表示右出，01表示左入，11表示右入
	 * 
	 * @param dataList
	 * @return
	 */
	private static String getDirFlag(ArrayList<DifPointTotalMapInfo> dataList) {
		// TODO Auto-generated method stub
		String enterLink = dataList.get(0).enter_out_DifPoint_Link.split("\\|")[0];
		int flag = dataList.get(0).flag == 0 ? 0 : dataList.get(0).flag;
		double stringAngle = 0;
		for (DifPointTotalMapInfo d : dataList) {
			if (d.flag == 0) {
				stringAngle = d.straight_angle;
			}
		}
		for (DifPointTotalMapInfo d : dataList) {
			if (d.flag != 0) {
				d.straight_angle = stringAngle;
			}
		}
		for (DifPointTotalMapInfo d : dataList) {

			flag = ((flag - d.flag) >= 0 ? flag : d.flag);
			if (!(d.enter_out_DifPoint_Link.split("\\|")[0].equals(enterLink))) {
				if (flag == 4) {
					// zuoru
					return "01";
				}
				if (flag == 5) {
					// youru
					return "11";
				}
			}
		}

		if (flag == 4) {
			// zuochu
			return "00";
		}
		if (flag == 5) {
			// youchu
			return "10";
		}
		return null;
	}

	private static void getSameNodeRoads(String closeroadmapdatafile, HashMap<String, ArrayList<DifPointTotalMapInfo>> sameNodeRoadsMap, int simplesmallnum, int roadclass) throws IOException {
		// TODO Auto-generated method stub
		BufferedReader br = new BufferedReader(new FileReader(new File(closeroadmapdatafile)));
		String line = "";
		HashSet<String> ss = new HashSet<String>();
		while ((line = br.readLine()) != null) {
			CloseRoadMapData closeRoadMapData = CloseRoadMapData.parseData(line);
			// 样本数小于simplesmallnum的舍弃
			if (closeRoadMapData.simpleNum < simplesmallnum)
				continue;
			// link序列有重复的舍弃
			if (hasSameLink(closeRoadMapData.linkseq))
				continue;
			String nodeId = closeRoadMapData.nodeId;
			ArrayList<DifPointTotalMapInfo> dataList = sameNodeRoadsMap.get(nodeId);
			DifPointTotalMapInfo difData = new DifPointTotalMapInfo(closeRoadMapData, roadClass);
			if (dataList == null) {
				dataList = new ArrayList<DifPointTotalMapInfo>();
				dataList.add(difData);
				sameNodeRoadsMap.put(nodeId, dataList);
			} else {
				boolean isSame = false;
				for (DifPointTotalMapInfo data : dataList) {
					if (data.linkArr.contains(difData.linkArr) || difData.linkArr.contains(data.linkArr)) {
						isSame = true;
					}
				}
				if (!isSame)
					dataList.add(difData);
			}
		}
	}

	/**
	 * 判断link序列中是否含有相同的link
	 * 
	 * @param linkseq
	 * @return
	 */
	private static boolean hasSameLink(String linkseq) {
		// TODO Auto-generated method stub
		HashSet<String> linkSet = new HashSet<String>();
		String[] linkSeq = linkseq.split("\\|");
		for (String link : linkSeq) {
			if (linkSet.contains(link)) {
				return true;
			} else {
				linkSet.add(link);
			}
		}
		return false;
	}

	private static void getLinkGeo(String rGMapFile, HashMap<String, Geometry> linkGeo, HashMap<String, Integer> linklen, HashMap<String, String> linkMeshIds, int cellsize, HashMap<String, String> linkAngle) throws IOException, ParseException {
		// TODO Auto-generated method stub
		BufferedReader br = new BufferedReader(new FileReader(new File(rGMapFile)));
		String line = "";
		// HashMap<String, Geometry> getLinkGeo = new HashMap<String,
		// Geometry>();
		// HashMap<String, String> getLinkLen = new HashMap<String, String>();
		// HashMap<String, String> getlinkMesh = new HashMap<String, String>();
		while ((line = br.readLine()) != null) {
			R_G_DATA data = R_G_DATA.parseData(line);
			String minmaxAngle = getAngle(data.linkSeqGEO.toString());
			linkAngle.put(data.linkId, minmaxAngle);
			linkGeo.put(data.linkId, data.linkSeqGEO);
			linklen.put(data.linkId, Integer.parseInt(data.linklength));
			getMeshIds(data, cellSize, linkMeshIds);
		}
	}

	private static String getAngle(String linkSeqGEO) {
		// TODO Auto-generated method stub
		// String linkAngleArr1 = linkSeqGEO.replace("LINESTRING", "").trim();
		// String linkAngleArr2 = linkAngleArr1.replace("(", "").trim();
		// String linkAngleArr3 = linkAngleArr2.replace(")", "").trim();
		// String[] linkAngleArr = linkAngleArr3.split(",");
		// // String[] linkAngleArr=linkSeqGEO.replace("LINESTRING",
		// // "").trim().replace("(", "").trim().replace(")",
		// // "").trim().split(",");
		// TreeMap<Double, Double> treeMap = new TreeMap<Double, Double>();
		// for (int i = 0; i < linkAngleArr.length - 1; i++) {
		// String[] lonlatArr = linkAngleArr[i].trim().split(" ");
		// double nowlon = Double.parseDouble(lonlatArr[0]);
		// double nowlat = Double.parseDouble(lonlatArr[1]);
		// String[] aftlonlatArr = linkAngleArr[i + 1].trim().split(" ");
		// double aftnowlon = Double.parseDouble(aftlonlatArr[0]);
		// double aftnowlat = Double.parseDouble(aftlonlatArr[1]);
		// double azimuth = MapUtil.azimuth(nowlon, nowlat, aftnowlon,
		// aftnowlat);
		// treeMap.put(azimuth, azimuth);
		// }
		// String minmax = treeMap.firstKey() + "_" + treeMap.lastKey();
		//
		// return minmax;
		String linkAngleArr1 = linkSeqGEO.replace("LINESTRING", "").trim();
		String linkAngleArr2 = linkAngleArr1.replace("(", "").trim();
		String linkAngleArr3 = linkAngleArr2.replace(")", "").trim();
		String[] linkAngleArr = linkAngleArr3.split(",");

		// TreeMap<Double, Double> treeMap = new TreeMap<Double, Double>();
		// for (int i = 0; i < linkAngleArr.length - 1; i++) {
		// String[] lonlatArr = linkAngleArr[i].trim().split(" ");
		// double nowlon = Double.parseDouble(lonlatArr[0]);
		// double nowlat = Double.parseDouble(lonlatArr[1]);
		// String[] aftlonlatArr = linkAngleArr[i + 1].trim().split(" ");
		// double aftnowlon = Double.parseDouble(aftlonlatArr[0]);
		// double aftnowlat = Double.parseDouble(aftlonlatArr[1]);
		// double azimuth = MapUtil.azimuth(nowlon, nowlat, aftnowlon,
		// aftnowlat);
		// treeMap.put(azimuth, azimuth);
		// }
		// for (int i = 0; i < 2; i++) {
		// String[] lonlatArr = linkAngleArr[i].trim().split(" ");
		// double nowlon = Double.parseDouble(lonlatArr[0]);
		// double nowlat = Double.parseDouble(lonlatArr[1]);
		// String[] aftlonlatArr = linkAngleArr[i + 1].trim().split(" ");
		// double aftnowlon = Double.parseDouble(aftlonlatArr[0]);
		// double aftnowlat = Double.parseDouble(aftlonlatArr[1]);
		// double azimuth = MapUtil.azimuth(nowlon, nowlat, aftnowlon,
		// aftnowlat);
		// treeMap.put(azimuth, azimuth);
		// }
		String[] lonlatArr = linkAngleArr[0].trim().split(" ");
		double nowlon = Double.parseDouble(lonlatArr[0]);
		double nowlat = Double.parseDouble(lonlatArr[1]);
		String[] aftlonlatArr = linkAngleArr[1].trim().split(" ");
		double aftnowlon = Double.parseDouble(aftlonlatArr[0]);
		double aftnowlat = Double.parseDouble(aftlonlatArr[1]);
		double azimuth = MapUtil.azimuth(nowlon, nowlat, aftnowlon, aftnowlat);

		String[] lonlatArr1 = linkAngleArr[linkAngleArr.length - 2].trim().split(" ");
		double nowlon1 = Double.parseDouble(lonlatArr1[0]);
		double nowlat1 = Double.parseDouble(lonlatArr1[1]);
		String[] aftlonlatArr1 = linkAngleArr[linkAngleArr.length - 1].trim().split(" ");
		double aftnowlon1 = Double.parseDouble(aftlonlatArr1[0]);
		double aftnowlat1 = Double.parseDouble(aftlonlatArr1[1]);
		double azimuth1 = MapUtil.azimuth(nowlon1, nowlat1, aftnowlon1, aftnowlat1);
		// treeMap.put(azimuth, azimuth);
		// String minmax = treeMap.firstKey() + "_" + treeMap.lastKey();
		String enterOut = azimuth + "_" + azimuth1;
		return enterOut;
	}

	/**
	 * 获取link所属meshid
	 * 
	 * @param data
	 * @param cellsize2
	 * @param getlinkMesh
	 * @return
	 */
	private static void getMeshIds(R_G_DATA data, int cellsize2, HashMap<String, String> getlinkMesh) {
		// TODO Auto-generated method stub
		HashSet<String> getMeshIds = new HashSet<String>();
		String line = data.linkSeqGEO.toString().replace("(", "").replace(")", "").replace("LINESTRING", "");
		String[] arr = line.split(",");
		for (String lonlat : arr) {
			String[] ll = lonlat.trim().split(" ");
			double lon = Double.parseDouble(ll[0]);
			double lat = Double.parseDouble(ll[1]);
			String meshId = MapUtil.findCell(lon, lat, 200);
			getMeshIds.add(meshId);
		}
		StringBuffer meshs = new StringBuffer();
		for (String meshId : getMeshIds) {
			meshs.append(meshId);
			meshs.append("|");
		}
		getlinkMesh.put(data.linkId, meshs.toString());
	}

	private static void test(String closeroadmapdatafile2) throws IOException {
		// TODO Auto-generated method stub
		BufferedReader br = new BufferedReader(new FileReader(new File(closeroadmapdatafile2)));
		String line = "";
		HashSet<String> ss = new HashSet<String>();

		while ((line = br.readLine()) != null) {
			String[] arr = line.split(",");
			ss.add(arr[6]);
		}

		System.out.println(ss.size());

		br.close();
		br = null;
	}

	/**
	 * 对单个红绿灯10字路口单方向单转向只保留一个，去掉重复记录数
	 * 
	 * @throws IOException
	 */
	private static void dataSplit(String inputfilefolder2, String closeroadmapdatafile2) throws IOException {
		// TODO Auto-generated method stub
		File[] files = new File(inputfilefolder2).listFiles();
		HashMap<String, String> dataMap = new HashMap<>();
		for (File file : files) {
			BufferedReader br = new BufferedReader(new FileReader(file));
			String line = "";
			while ((line = br.readLine()) != null) {
				String[] arr = line.split(":");
				String pointID_angle_flag = arr[1] + "_" + arr[7] + "_" + arr[9];
				dataMap.put(pointID_angle_flag, line);
			}
			br.close();
			br = null;
		}
		BufferedWriter write = new BufferedWriter(new FileWriter(new File(closeroadmapdatafile2)));
		for (Map.Entry<String, String> entry : dataMap.entrySet()) {
			write.write(entry.getValue());
			write.newLine();
			write.flush();
		}
		write.close();
		write = null;
	}

	/**
	 * 将多个文件数据整合到一个文件中
	 * 
	 * @param outfile2
	 * 
	 * @throws IOException
	 */
	private static void intergrationMapAttr(String closeroadturnattrfile2, String closeroadlinklengthfile2, String outfile2) throws IOException {
		// TODO Auto-generated method stub
		/** key:pointID_flag_angle;value:形狀 **/
		HashMap<String, Geometry> difPointEndRoadBuffer = DifPointRoadGeoService.getDifPointRoadBuffer(closeRoadMapDataFile, R_G_Map_File);
		BufferedReader br1 = new BufferedReader(new FileReader(new File(closeroadturnattrfile2)));
		BufferedReader br2 = new BufferedReader(new FileReader(new File(closeroadlinklengthfile2)));
		BufferedWriter write = new BufferedWriter(new FileWriter(new File(outfile2)));
		String line2 = "";
		HashMap<String, String> linkLenMap2 = new HashMap<>();
		while ((line2 = br2.readLine()) != null) {
			String[] arr = line2.split(",");
			linkLenMap2.put(arr[0], arr[1]);
		}
		br2.close();
		br2 = null;
		String line1 = "";

		while ((line1 = br1.readLine()) != null) {
			CloseRoadMapData data = CloseRoadMapData.parseData1(line1);
			String[] mapData = line1.split(",");
			String difPointId = data.nodeId;
			int angle = data.angel;
			int dir = data.flag;
			String key = difPointId + "_" + dir + "_" + angle;
			String linkLenSeq = linkLenMap2.get(key);
			if (difPointEndRoadBuffer.get(key) == null) {
				continue;
			}
			String roadGeoInfo = difPointEndRoadBuffer.get(key).toString();
			String[] lonlatArr = roadGeoInfo.replace("POLYGON ((", "").replace("))", "").replace(")", "").replace("(", "").split(",");
			Set<String> meshSet = new HashSet<>();
			for (int i = 0; i < lonlatArr.length; i++) {

				double lon = Double.parseDouble(lonlatArr[i].trim().split(" ")[0]);
				double lat = Double.parseDouble(lonlatArr[i].trim().split(" ")[1]);
				int meshId = MapUtil.findMesh(lon, lat);
				String meshMinId = MapUtil.findCell(lon, lat, 100);
				meshSet.add(meshMinId);

			}

			String roadId = data.roadId;
			String linkIdSeq = data.linkseq;
			String linkDisSeqFromLeft = data.disSeq;
			int totalLen = data.totalLen;
			int befDis = data.beforeRoadDis;
			String bef_aft_difPoint_link = data.inRoadId + "|" + data.outRoadId;
			String nodeId = data.nodeId;
			double lon = data.lon;
			double lat = data.lat;
			int straightAngle = data.angel;
			int flag = data.flag;
			int difPointDisFormRight = data.afterRoadDis;
			String turnFlag = data.turnFlag;
			String linkLenSeq1 = linkLenSeq;
			straightAngle = data.angel;
			String meshIds = "";
			for (String meshId : meshSet) {
				meshIds += meshId + "|";
			}
			String outLine = roadId + "," + linkIdSeq + "," + linkDisSeqFromLeft + "," + totalLen + "," + befDis + "," + bef_aft_difPoint_link + "," + nodeId + "," + lon + "," + lat + "," + straightAngle + "," + flag + "," + difPointDisFormRight + "," + turnFlag + "," + linkLenSeq1 + "," + straightAngle + "," + meshIds + "," + roadGeoInfo;
			write.write(outLine);
			write.newLine();
			write.flush();
		}
		write.close();
		write = null;
		br1.close();
		br1 = null;
	}

	/**
	 * 生成link长度对应表
	 * 
	 * @throws IOException
	 * @throws NumberFormatException
	 */
	private static void getLinkLen(String inputFile, String outputFile) throws NumberFormatException, IOException {
		// TODO Auto-generated method stub
		BufferedReader br = new BufferedReader(new FileReader(new File(inputFile)));
		BufferedWriter write = new BufferedWriter(new FileWriter(new File(outputFile)));
		String line = "";
		while ((line = br.readLine()) != null) {
			// System.out.println(line);
			CloseRoadMapData closeRoadData = CloseRoadMapData.parseData1(line);
			String[] linkArr = closeRoadData.linkseq.split("\\|");
			int totalLength = closeRoadData.totalLen;
			String[] LinkDisArr = closeRoadData.disSeq.split("\\|");
			String dif_Point_Id = closeRoadData.nodeId;
			int angle = closeRoadData.angel;
			int flag = closeRoadData.flag;
			int dataLen = linkArr.length;

			String outLine = dif_Point_Id + "_" + flag + "_" + angle + ",";
			String firstLinkId = linkArr[0];
			String firstLinkLen = LinkDisArr[1];
			outLine += firstLinkId + ":" + firstLinkLen + "|";

			for (int i = 1; i < dataLen - 1; i++) {
				String linkId = linkArr[i];
				int linkLen = Integer.parseInt(LinkDisArr[i + 1]) - Integer.parseInt(LinkDisArr[i]);
				outLine += linkId + ":" + linkLen + "|";
			}
			String lastLinkId = linkArr[dataLen - 1];
			int lastLinkLen = totalLength - Integer.parseInt(LinkDisArr[dataLen - 1]);
			outLine += lastLinkId + ":" + lastLinkLen + "|";
			System.out.println(outLine);
			write.write(outLine);
			write.newLine();
			write.flush();
		}
	}

	/**
	 * 获取转向标志： 00表示左出，10表示右出，02掉头,20直行
	 */
	private static void getCloseRoadTurnAttr(String inPutFile, String outPutFile) throws IOException {
		// TODO Auto-generated method stub

		HashMap<String, TreeMap<Integer, String>> sameDifPointMap = new HashMap<>();
		BufferedReader br = new BufferedReader(new FileReader(inPutFile));
		BufferedWriter write = new BufferedWriter(new FileWriter(new File(outPutFile)));
		String line = "";
		while ((line = br.readLine()) != null) {
			CloseRoadMapData closeRoadData = CloseRoadMapData.parseData(line);
			/**
			 * 根据转向标志位，标志位: 0:直行3:掉头4: 左转5: 右转;判断转向标志
			 * 00表示左出，10表示右出，02表示掉头,20表示直行
			 **/
			int flag = closeRoadData.flag;
			String turnFlag = "";
			switch (flag) {
			case 0:
				turnFlag = "20";
				break;
			case 3:
				turnFlag = "02";
				break;
			case 4:
				turnFlag = "00";
				break;
			case 5:
				turnFlag = "10";
				break;
			default:
				break;
			}
			closeRoadData.turnFlag = turnFlag;
			System.out.println(closeRoadData.toString1());
			write.write(closeRoadData.toString1());
			write.newLine();
			write.flush();
		}
	}

}
